package com.ygqh.baby.handler;

import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.ProductStatus;
import com.ygqh.baby.ao.SalesPlatform;
import com.ygqh.baby.constant.RedisConstant;
import com.ygqh.baby.model.ProductListRequestParam;
import com.ygqh.baby.po.YgCategory;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.YgCategoryService;
import com.ygqh.baby.solr.YgSolrClient;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.GroupCommand;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.GroupParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: sunshuo
 * @Date: 2019/4/26 12:17
 * @Version: 1.0
 */
@Component
public class ProductSolrHandler {

    private final static Integer QUERY_START = 0;
    private final static Integer QUERY_MAX_ROWS = 100;
    private final static SolrClient SOLR_CLIENT = YgSolrClient.INSTANCE.getSolrClient();

    @Autowired
    private RedisDao redisDao;
    @Autowired
    private YgCategoryService ygCategoryService;

    /**
     * 查询商品信息
     *
     * @param param 页面请求数据
     * @return
     */
    public SolrDocumentList productList(ProductListRequestParam param) {
        try {
            System.err.println("ping solr  result:" + SOLR_CLIENT.ping().toString());
            SolrQuery query = new SolrQuery();

            buildProductNameQuery(query, param.getProductName());
            buildCategoryIdsQuery(query, param.getCategoryIds());
            buildPreSaleDateQuery(query, param.getIsPreProduct());
            buildGenderQuery(query, param.getGender());
            buildTagsQuery(query, param.getTags());
            buildSupplierIdQuery(query, param.getSupplierId());
            buildSaleStatusQuery(query, param.getSaleStatus());
            buildSizeNameQuery(query, param.getSizeName());
            buildCategoryNamesQuery(query, param.getSelect1(), param.getSelect2(), param.getSelect3());
            buildSalesPlatformQuery(query, param.getSalesPlatform());

            buildSortQuery(query, param.getSortKey(), param.getDir(),param.isSearch());
            buildPageQuery(query, param.getStart(), param.getLimit());

            QueryResponse response = SOLR_CLIENT.query(query, SolrRequest.METHOD.POST);
            return response.getResults();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据id集查询商品信息
     *
     * @param productIdList id集
     * @param param         页面请求数据
     * @return
     */
    public SolrDocumentList productListByIdList(List<Long> productIdList, ProductListRequestParam param) {
        if (CollectionUtils.isEmpty(productIdList)) {
            return null;
        }
        try {
            SolrQuery query = new SolrQuery("*:*");
            String pids = StringUtils.join(productIdList, " OR ");
            query.addFilterQuery("id:" + "(" + pids + ")");
            buildSalesPlatformQuery(query, param.getSalesPlatform());
            buildSaleStatusQuery(query, param.getSaleStatus());
            buildSortQuery(query, param.getSortKey(), param.getDir(), param.isSearch());
            buildPageQuery(query, param.getStart(), param.getLimit());
            QueryResponse response = SOLR_CLIENT.query(query, SolrRequest.METHOD.POST);
            return response.getResults();
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 按二级分类分组获取最新上架商品
     *
     * @param param 页面请求数据
     * @return
     */
    public SolrDocumentList productListGroupBySecondaryCategory(ProductListRequestParam param) {
        try {
            SolrQuery query = new SolrQuery("-categoryNames:\"品牌团购\"");
            if (CollectionUtils.isNotEmpty(param.getSkipIdList())) {
                String pIds = StringUtils.join(param.getSkipIdList(), " OR ");
                query.addFilterQuery("-id:" + "(" + pIds + ")");
            }
            if (CollectionUtils.isNotEmpty(param.getSkipScIdList())) {
                String scIds = StringUtils.join(param.getSkipScIdList(), " OR ");
                query.addFilterQuery("-groupId:" + "(" + scIds + ")");
            }
            buildSalesPlatformQuery(query, param.getSalesPlatform());
            buildSaleStatusQuery(query, param.getSaleStatus());
            // 按二级分类分组
            query.setParam(GroupParams.GROUP_FIELD, "secondaryCategoryId")
                    .setParam(GroupParams.GROUP_SORT, "saleTime desc");
            return queryByGroup(query, param);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 按款式分组获取最新商家商品
     *
     * @param param 页面请求数据
     * @return
     */
    public SolrDocumentList productListGroupByProductGroup(ProductListRequestParam param) {
        try {
            SolrQuery query = new SolrQuery("*:*");
            buildCategoryNamesQuery(query, param.getSelect1(), param.getSelect2(),
                    param.getSelect3());
            buildSalesPlatformQuery(query, param.getSalesPlatform());
            buildSaleStatusQuery(query, param.getSaleStatus());
            // 按款式分组
            query.setParam("group.field", "groupId")
                    .setParam("group.sort", "saleTime desc");
            return queryByGroup(query, param);
        } catch (SolrServerException | IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 分页查询
     *
     * @param query query
     * @param start 分页开始
     * @param limit 返回多少条
     */
    private void buildPageQuery(SolrQuery query, Integer start, Integer limit) {
        if (start != null) {
            query.setStart(start);
            query.setRows(limit);
        }
    }

    /**
     * 查询结果排序
     *
     * @param query   query
     * @param sortKey 排序字段
     * @param dir     排序顺序
     */
    private void buildSortQuery(SolrQuery query, String sortKey, String dir, boolean search) {
        if (StringUtils.isNotBlank(sortKey)) {
            String solrSortColumn = this.getSolrSortColumn(sortKey);
            query.setSort(solrSortColumn, SolrQuery.ORDER.valueOf(dir));
        } else if (!search) {
            query.setSort("saleTime", SolrQuery.ORDER.desc);
        }
    }

    /**
     * 销售平台
     *
     * @param query         query
     * @param salesPlatform 销售平台
     */
    private void buildSalesPlatformQuery(SolrQuery query, String salesPlatform) {
        if (salesPlatform != null) {
            query.addFilterQuery("salesPlatform:\"" + salesPlatform + "\"");
        }
    }

    /**
     * 三级分类名称查询
     *
     * @param query   query
     * @param select1 一级分类
     * @param select2 二级分类
     * @param select3 三级分类
     */
    private void buildCategoryNamesQuery(SolrQuery query, String[] select1, String[] select2, String[] select3) {
        if (select1 != null && select1.length > 0) {
            StringBuilder select1Query = new StringBuilder();
            for (String select : select1) {
                select1Query.append("categoryNames:").append("\"").append(select).append("\"")
                        .append(" OR ");
            }
            String substring = select1Query.substring(0, select1Query.length() - 4);
            query.addFilterQuery(substring);
        }
        if (select2 != null && select2.length > 0) {
            StringBuilder select2Query = new StringBuilder();
            for (String select : select2) {
                select2Query.append("categoryNames:").append("\"").append(select).append("\"")
                        .append(" OR ");
            }
            String substring = select2Query.substring(0, select2Query.length() - 4);
            query.addFilterQuery(substring);
        }
        if (select3 != null && select3.length > 0) {
            StringBuilder select3Query = new StringBuilder();
            for (String select : select3) {
                select3Query.append("basicAttribute:").append("\"").append(select).append("\"")
                        .append(" OR ").append("tags:").append("\"").append(select).append("\"").append(" OR ");
            }
            String substring = select3Query.substring(0, select3Query.length() - 4);
            query.addFilterQuery(substring);
        }
    }

    /**
     * 商品尺码
     *
     * @param query    query
     * @param sizeName 尺码
     */
    private void buildSizeNameQuery(SolrQuery query, String[] sizeName) {
        if (sizeName != null && sizeName.length > 0) {
            StringBuilder sizeNames = new StringBuilder();
            for (String select : sizeName) {
                sizeNames.append("sizeNames:").append(select).append(" OR ");
            }
            String substring = sizeNames.substring(0, sizeNames.length() - 4);
            query.addFilterQuery(substring);
        }
    }

    /**
     * 上下架状态
     *
     * @param query      query
     * @param saleStatus 上下架状态
     */
    private void buildSaleStatusQuery(SolrQuery query, ProductStatus saleStatus) {
        if (saleStatus != null) {
            query.addFilterQuery("saleStatus:" + saleStatus);
        }
    }

    /**
     * 指定商家
     *
     * @param query      query
     * @param supplierId 商家id
     */
    private void buildSupplierIdQuery(SolrQuery query, Long supplierId) {
        if (supplierId != null) {
            query.addFilterQuery("supplierId:" + supplierId);
        }
    }

    /**
     * 销售标签
     *
     * @param query query
     * @param tags  销售标签
     */
    private void buildTagsQuery(SolrQuery query, String tags) {
        if (tags != null) {
            query.addFilterQuery("tags:\"" + tags + "\"");
        }
    }

    /**
     * 性别
     *
     * @param query  query
     * @param gender 性别
     */
    private void buildGenderQuery(SolrQuery query, String gender) {
        if (StringUtils.isNotBlank(gender) && !"0,1".equals(gender)) {
            query.addFilterQuery("gender:" + gender);
        }
    }

    /**
     * 预售期
     *
     * @param query        query
     * @param isPreProduct 是否为预售商品
     */
    private void buildPreSaleDateQuery(SolrQuery query, Boolean isPreProduct) {
        if (isPreProduct != null) {
            if (isPreProduct) {
                query.addFilterQuery("preSaleDate:*");
            } else {
                query.addFilterQuery("-preSaleDate:*");
            }
        }
    }

    /**
     * 多级分类id
     *
     * @param query       query
     * @param categoryIds 分类id集
     */
    private void buildCategoryIdsQuery(SolrQuery query, Long[] categoryIds) {
        if (categoryIds != null && categoryIds.length > 0) {
            List<YgCategory> categorys = ygCategoryService.findByIds(categoryIds);
            // 存放三级id
            List<Long> tIds = new ArrayList<>();
            if (categorys != null && categorys.size() > 0) {
                // 存放二级id
                List<Long> sIds = new ArrayList<>();
                for (YgCategory category : categorys) {
                    if (category.getLevel().equals(Long.valueOf("2"))) {
                        sIds.add(category.getId());
                    } else {
                        tIds.add(category.getId());
                    }
                }
                List<YgCategory> categories = ygCategoryService.findByParentIds(sIds);
                categories.forEach((cate) -> tIds.add(cate.getId()));
            } else {
                tIds.addAll(Arrays.asList(categoryIds));
            }
            String cIds = StringUtils.join(tIds, " OR ");
            query.addFilterQuery("categoryId:" + "(" + cIds + ")");
        }
    }

    /**
     * 搜索框
     *
     * @param query     query
     * @param searchKey 搜索词
     */
    private void buildProductNameQuery(SolrQuery query, String searchKey) {
        StringBuilder sb = new StringBuilder();
        if (StringUtil.isNotBlank(searchKey)) {
            sb.append("productName:").append(searchKey)
                    .append(" OR ").append("tags:").append(searchKey)
                    .append(" OR ").append("basicAttribute:").append(searchKey)
                    .append(" OR ").append("sizeNames:").append(searchKey)
                    .append(" OR ").append("categoryNames:").append(searchKey);
        } else {
            sb.append("*:*");
        }
        query.setQuery(sb.toString());
    }

    /**
     * 计算分享返利价格
     *
     * @param results 结果集
     */
    public void processSharePriceForYjdian(SolrDocumentList results) {
        if (results == null || results.size() == 0) {
            return;
        }
        String key = String.format(RedisConstant.NEW_CUSTOM_COUPON_PRICE_PREFIX_KEY, SalesPlatform.Yijiadian);
        String priceValue = redisDao.get(key);
        BigDecimal couponPrice;
        if (StringUtils.isNotBlank(priceValue)) {
            couponPrice = new BigDecimal(priceValue);
        } else {
            couponPrice = BigDecimal.valueOf(5);
        }
        results.forEach(result -> {
            BigDecimal shareRate = new BigDecimal(result.getFieldValue("shareRate").toString());
            BigDecimal promotionPrice = null;
            if (result.getFieldValue("promotionPrice") != null
                    && "".equals(result.getFieldValue("promotionPrice"))) {
                promotionPrice = new BigDecimal(result.getFieldValue("promotionPrice").toString());
            }
            BigDecimal productSalePrice = new BigDecimal(result.getFieldValue("productSalePrice").toString());
            BigDecimal price;
            BigDecimal newCustomPrice;
            if (promotionPrice == null || promotionPrice.compareTo(BigDecimal.ZERO) == 0) {
                price = productSalePrice;
                newCustomPrice = price.compareTo(couponPrice) < 0 ? price : price.subtract(couponPrice);
            } else {
                price = promotionPrice;
                newCustomPrice = BigDecimal.ZERO;
            }
            BigDecimal sharePrice = price.multiply(shareRate).setScale(1, BigDecimal.ROUND_HALF_UP);
            result.addField("sharePrice", sharePrice);
            result.setField("newCustomPrice", newCustomPrice);
        });
    }

    /**
     * 获取排序字段
     *
     * @param sortKey 排序字段
     * @return
     */
    private String getSolrSortColumn(String sortKey) {
        if ("product_sale_price".equals(sortKey)) {
            return "sortSalePrice";
        }
        if (!sortKey.contains("_")) {
            return sortKey;
        }
        String[] split = sortKey.split("_");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < split.length; i++) {
            String string = split[i];
            if (i > 0) {
                String first = string.substring(0, 1);
                String last = string.substring(1);
                string = first.toUpperCase() + last;
            }
            sb.append(string);
        }
        return sb.toString();
    }

    /**
     * Solr分组查询
     *
     * @param queryByGroup 分组查询条件
     * @param param        页面请求数据
     * @return
     * @throws IOException
     * @throws SolrServerException
     */
    private SolrDocumentList queryByGroup(SolrQuery queryByGroup, ProductListRequestParam param)
            throws IOException, SolrServerException {
        queryByGroup.setParam(GroupParams.GROUP, true)
                .setParam(GroupParams.GROUP_TOTAL_COUNT, true)
                .setParam(GroupParams.GROUP_FORMAT, "simple");
        queryByGroup.addTermsField("id");
        Integer start = QUERY_START;
        buildPageQuery(queryByGroup, start, QUERY_MAX_ROWS);
        QueryResponse response = SOLR_CLIENT.query(queryByGroup, SolrRequest.METHOD.POST);
        GroupCommand groupCommand = response.getGroupResponse().getValues().get(0);
        Integer totalCount = groupCommand.getNGroups();
        if (totalCount == null || totalCount == 0) {
            return null;
        }
        // 分组后结果商品id集
        List<Long> resultIdList = new ArrayList<>();
        SolrDocumentList result = groupCommand.getValues().get(0).getResult();
        for (SolrDocument document : result) {
            resultIdList.add(Long.valueOf(document.get("id").toString()));
        }
        if (totalCount > QUERY_MAX_ROWS) {
            int totalPage = (totalCount / QUERY_MAX_ROWS) + ((totalCount % QUERY_MAX_ROWS) == 0 ? 0 : 1);
            for (int i = 0; i < totalPage; i++) {
                start = (i + 1) * QUERY_MAX_ROWS;
                queryByGroup.setStart(start);
                response = SOLR_CLIENT.query(queryByGroup, SolrRequest.METHOD.POST);
                groupCommand = response.getGroupResponse().getValues().get(0);
                result = groupCommand.getValues().get(0).getResult();
                for (SolrDocument document : result) {
                    resultIdList.add(Long.valueOf(document.get("id").toString()));
                }
            }
        }
        System.out.println(resultIdList);
        if (CollectionUtils.isNotEmpty(param.getSkipIdList())) {
            resultIdList.removeAll(param.getSkipIdList());
        }
        SolrQuery query = new SolrQuery("id:(" + StringUtils.join(resultIdList, " OR ") + ")");
        buildSortQuery(query, param.getSortKey(), param.getDir(),param.isSearch());
        buildPageQuery(query, param.getStart(), param.getLimit());
        response = SOLR_CLIENT.query(query, SolrRequest.METHOD.POST);
        return response.getResults();
    }
}
